#include "os_timer.h"
#include "delay.h"
#include "uart.h"

static os_timer_t os_timer_root = { 0 };
static os_timer_t* os_timer_tail;
static uint8_t tid=0;

/**
 * @brief 初始化一个定时器
 *
 * @param ptimer os_timer_t指针（必须是静态的！不然内存被回收了就跑飞了）
 * @param pfunction 定时器时间到后要运行的函数
 * @param parg 要运行的函数的参数
 */
void os_timer_init(os_timer_t* ptimer, os_timer_func_t pfunction, void* parg)
{
    if (0 == os_timer_tail || 0 == ptimer || pfunction == 0)
    {
        // rt_kprintf("os_timer_init error\n");
        return;
    }
    tid++;
    os_timer_tail->timer_next = ptimer;
    os_timer_tail = ptimer;
    ptimer->timer_func = pfunction;
    ptimer->timer_arg = parg;
    ptimer->timer_next = 0;
    ptimer->timer_id = tid;
    // rt_kprintf("id:%d t:0x%08X \t f:0x%08X p:0x%08X\n",ptimer->timer_id, ptimer,pfunction,parg);
}
/**
 * @brief 取消轮询
 *
 * @param ptimer
 */
void os_timer_destroy(os_timer_t* ptimer)
{
    os_timer_t* p = &os_timer_root;
    while (p->timer_next != 0)
    {
        if (p->timer_next == ptimer)
        {
            p->timer_next = ptimer->timer_next;
            break;
        }
        else
        {
            p = p->timer_next;
        }
    }
}
/**
 * @brief 启动定时器
 *
 * @param ptimer
 * @param ms 多少ms后运行
 * @param repeat_flag 是否要重复运行1：yes
 */
void os_timer_start(os_timer_t* ptimer, uint32_t ms, bool repeat_flag)
{
    ptimer->timer_period = ms;
    ptimer->repeat = repeat_flag;
    ptimer->start = 1;
    ptimer->timer_current = millis();
}
/**
 * @brief 停止定时器
 *
 * @param ptimer
 */
void os_timer_stop(os_timer_t* ptimer)
{
    ptimer->start = 0;
}
/**
 * @brief 定时器轮询初始化，必须要在添加第一个定时器前执行一次
 *
 */
void os_timer_routine_init()
{
    // rt_kprintf("%s %d\n",__FILE__,__LINE__);
    os_timer_root.timer_next = 0;
    os_timer_root.timer_func = 0;
    os_timer_root.timer_id = 0;
    os_timer_root.start = 1;
    os_timer_root.timer_period = 1000;
    os_timer_tail = &os_timer_root;

}
/**
 * @brief 软件定时器任务轮询（升级版每...ms,运行...）
 *
 */
void os_timer_routine(void)
{
    if (os_timer_root.start == 0)
    {
        os_timer_root.start = 1;
        os_timer_routine_init();
    }

    os_timer_t* p;
    p = os_timer_root.timer_next;
    while (p != 0)
    {
        if (p->start == 1)
        {
            if (millis() >= (p->timer_period + p->timer_current))
            {
                if (p->repeat == 1)
                {
                    p->timer_current = millis();
                }
                else
                {
                    p->start = 0;
                }
                if (p->timer_func != 0)
                {
                    p->timer_func(p->timer_arg);
                }
            }
        }
        p = p->timer_next;
    }
}
void check_os_timer_list()
{
    os_timer_t* p = os_timer_root.timer_next;
    rt_kprintf("os_timer_list:\n");
    while (p != 0)
    {
        rt_kprintf("T%02d:0x%08X \tPeriod:%dms, \tfn:0x%0X\n", p->timer_id, p, p->timer_period, p->timer_func);
        p = p->timer_next;
    }
}

#if 0
static os_timer_t t0, t1, t2, t3;
void t0_fun(void* arg)
{
    rt_kprintf("t0 fun...\r\n");
}
void t1_fun(void* arg)
{
    rt_kprintf("t1 fun...\r\n");
}
void t2_fun(void* arg)
{
    rt_kprintf("t2 fun...\r\n");
}
void t3_fun(void* arg)
{
    rt_kprintf("t3 fun...\r\n");
    os_timer_destroy(&t3);
    check_os_timer_list();
}
void os_timer_test()
{
    os_timer_routine();


    static uint8_t isInit = 0;


    if (!isInit)
    {
        isInit = 1;
        os_timer_init(&t0, t0_fun, 0);
        os_timer_init(&t1, t1_fun, 0);
        os_timer_init(&t2, t2_fun, 0);
        os_timer_init(&t3, t3_fun, 0);

        os_timer_start(&t0, 1000, 1);
        os_timer_start(&t1, 200, 1);
        os_timer_start(&t2, 50, 1);
        os_timer_start(&t3, 5000, 0);


        check_os_timer_list();
    }




}
#endif
